import * as PIXI from "pixi.js";
import gsap from "gsap/all";
import EventEmitter from "eventemitter3";
import { parseColor } from "../util";

// 红包雨计时模块
export class Timer extends EventEmitter {
  remainTime; // 剩余时间

  maskRect = null; // 进度条遮罩

  progressPoint = null; // 进度条游标

  remainTimeValue = null; // 剩余时间元素

  remainTimeLabel = null; // 剩余时间文案元素

  progressContainer = null; // 进度条容器

  total; // 总时长

  duration = 1000; // 定时器触发间隔

  constructor(app, gameConfig) {
    super();
    const { countdownTotal = 30000 } = this.gameConfig.animations || {};
    this.total = countdownTotal;
    this.remainTime = countdownTotal;
  }

  //   开始计时
  start() {
    this.draw();
    const timer = setInterval(() => {
      this.remainTime -= this.duration;
      this.emit("timeChange", this.remainTime);

      if (this.remainTime <= 0) {
        clearInterval(timer);
        this.emit("timeEnd");
      }
    }, this.duration);

    this.countDownAnimate();
  }

  /**
   *
   * 下面是倒计时的绘制逻辑部分
   */

  //   格式化时间
  formatSecond(m) {
    return Math.floor(m / 1000);
  }

  //   相对容器垂直居中
  makeCenter(container, element) {
    const containerHeight = container.height;
    const elementHeight = element.height;
    element.y = (containerHeight - elementHeight) / 2;
  }

  //   绘制剩余时间标签文案
  drawRemainTimeLabel() {
    const { remainTimeLabel = "剩余时间", remainTimeColor = "#ffffff" } =
      this.gameConfig?.styles?.countdown || {};

    const text = new PIXI.Text(remainTimeLabel, {
      fontSize: 16,
      fill: parseColor(remainTimeColor),
      fontFamily: "PingFangSC-Regular",
    });

    text.resolution = 3;

    return text;
  }

  //   绘制剩余时间
  drawRemainTimeValue() {
    const { remainTimeValueColor = "#ffffff" } =
      this.gameConfig?.styles?.countdown || {};

    const remainTimeValue = new PIXI.Text(`${this.formatSecond(this.total)}s`, {
      fontSize: 24,
      fill: parseColor(remainTimeValueColor),
    });

    remainTimeValue.resolution = 3;
    remainTimeValue.x = this.app.screen.width - 62;
    this.on("timeChange", (value) => {
      remainTimeValue.text = `${this.formatSecond(value)}s`;
    });
    return remainTimeValue;
  }

  //   绘制进度条
  drawProgress() {
    const {
      progressPoint = DEFAILT_PROGRESS_POINT,
      progressLeftBorder = DEFAULT_BORDER_LEFT,
      progressRightBorder = DEFAULT_BORDER_RIGHT,
    } = this.gameConfig.assets || {};
    const { insideRectColor = "#ffffff", outsideRectColor = "#000000" } =
      this.gameConfig?.styles?.countdown || {};

    const remainTimeValueX = this.remainTimeValue?.x || 0;
    // 外矩形
    const outsideRect = new PIXI.Graphics();
    outsideRect.beginFill(parseColor(outsideRectColor));
    outsideRect.drawRect(83, 0, remainTimeValueX - 91 - 12, 16);
    outsideRect.endFill();

    // 内矩形
    const insideRect = new PIXI.Graphics();
    insideRect.beginFill(parseColor(insideRectColor));
    insideRect.drawRect(83, 3, remainTimeValueX - 93 - 12, 10);
    insideRect.endFill();

    // 遮罩矩形，进度条动画效果主要靠改变这个遮罩的x坐标
    this.maskRect = new PIXI.Graphics();
    this.maskRect.beginFill(parseColor(outsideRectColor));
    this.maskRect.drawRect(85, 3, remainTimeValueX - 95 - 12, 10);
    this.maskRect.endFill();

    // 左边框
    const leftBorder = PIXI.Sprite.from(progressLeftBorder);
    this.app.stage.addChild(leftBorder);
    leftBorder.width = 7;
    leftBorder.height = 16;
    leftBorder.x = 76;
    leftBorder.y = 0;

    // 右边框
    const rightBorder = PIXI.Sprite.from(progressRightBorder);
    this.app.stage.addChild(rightBorder);
    rightBorder.width = 6;
    rightBorder.height = 16;
    rightBorder.x = remainTimeValueX - 20;
    rightBorder.y = 0;

    // 进度点
    this.progressPoint = PIXI.Sprite.from(progressPoint);
    this.app.stage.addChild(this.progressPoint);
    this.progressPoint.width = 12;
    this.progressPoint.height = 12;
    this.progressPoint.x = 78;
    this.progressPoint.y = 2;

    // 外层遮罩，作用可以理解为overflow: hidden
    const mask = new PIXI.Graphics();
    mask.beginFill(parseColor(outsideRectColor));
    mask.drawRect(77, 0, remainTimeValueX - 97, 16);
    mask.endFill();

    // 遮罩内容器
    const innerContainer = new PIXI.Container();
    innerContainer.addChild(outsideRect, insideRect, this.maskRect, mask);
    innerContainer.mask = mask;

    // 遮罩外容器
    const outContainer = new PIXI.Container();
    outContainer.addChild(this.progressPoint);

    // 总容器
    const container = new PIXI.Container();
    container.addChild(innerContainer, outContainer);

    return container;
  }

  //   绘制顶部容器
  drawTopContainer() {
    const container = new PIXI.Container();
    container.addChild(
      this.remainTimeLabel,
      this.remainTimeValue,
      this.progressContainer
    );
    container.x = 12;
    container.y = 30;
    this.app.stage.addChild(container);
    return container;
  }

  //   绘制倒计时
  draw() {
    // 左边剩余时间文案
    this.remainTimeLabel = this.drawRemainTimeLabel();

    // 右边倒计时描述
    this.remainTimeValue = this.drawRemainTimeValue();

    // 进度条
    this.progressContainer = this.drawProgress();

    // 顶部倒计时容器
    const container = this.drawTopContainer();

    // 内部元素居中对齐
    this.makeCenter(container, this.remainTimeLabel);
    this.makeCenter(container, this.remainTimeValue);
    this.makeCenter(container, this.progressContainer);
  }

  //   倒计时进度动画绘制
  countDownAnimate() {
    if (!this.maskRect) return;
    gsap.to(this.maskRect, {
      x: this.maskRect?.width,
      duration: this.formatSecond(this.total),
      ease: "none",
    });
    gsap.to(this.progressPoint, {
      x: this.maskRect?.width + 78,
      duration: this.formatSecond(this.total),
      ease: "none",
    });
  }
}
